package eu.webhib.frmwrk.utils;

import java.io.*;
import java.util.*;
import org.apache.log4j.Logger;

/** 
 * Handles the properties of the application
 */
public class ApplProperties {

   private static final Logger log = Logger.getLogger(ApplProperties.class);
   /** The properties of the application */
   private static final ExtendedProperties prop = new ExtendedProperties();

   private ApplProperties() {
   }

   /**
    * Load Properties from given properties-Filename. First the file is looked up in the war archive.
    * Then the file is scanned in the given list of directories
    * @param fileName file name of properties file
    * @param externalDirs list of directories scanned for the properties file
    * @return The effective properties loaded. A property overwrites the same property loaded earlier.
    */
   public static ExtendedProperties loadProperties(String fileName, String[] externalDirs) {

      boolean found = false;

      /** try to load from deployed war archive */
      try {
         InputStream stream = ApplProperties.class.getClassLoader().getResourceAsStream(fileName);
         if (stream == null) {
            log.info("Properties file '" + fileName + "' not found in war archive");
         } else {
            prop.load(stream);
            log.info("Properties file '" + fileName + "' loaded from war archive");
            stream.close();
            found = true;
         }
      } catch (Exception ex) {
         log.fatal("Error reading properties file '" + fileName + "' from war archive", ex);
      }

      /** try to load from given directories */
      for (String dir : externalDirs) {
         if (checkAndLoadPropertiesFile(dir, fileName)) {
            found = true;
         }
      }

      log.info("Effective Properties: " + prop.size());
      List keyList = new ArrayList(prop.keySet());
      Collections.sort(keyList);
      for (Object key : keyList) {
         log.info(" " + key + "=" + prop.get(key));
      }
      return found ? prop : null;
   }

   /**
    * Helper for lookup and load the properties file in the given directory
    * @param dirPath directory path the file is tried to loaded
    * @param fileName properties file name
    * @return if file was found in the directory
    */
   private static boolean checkAndLoadPropertiesFile(String dirPath, String fileName) {
      if (dirPath == null) {
         return false;
      }
      String filePath = dirPath + Consts.FILE_SEPARATOR + fileName;
      File propFile = new File(filePath);
      try {
         filePath = propFile.getCanonicalPath();
      } catch (IOException ex) {
      }
      if (!propFile.exists()) {
         log.debug("Properties file '" + filePath + "' not found");
         return false;
      }
      try {
         Reader reader = new FileReader(propFile);
         prop.load(reader);
         log.info("Properties file '" + filePath + "' loaded");
         return true;
      } catch (Exception ex) {
         log.fatal("Error reading properties file: " + filePath, ex);
         return false;
      }
   }

   /**
    * Returns the application propertiers
    */
   public static ExtendedProperties getProperties() {
      return prop;
   }

   public static String get(String key) {
      return prop.get(key);
   }

   public static int getInt(String key) {
      return prop.getInt(key);
   }

   public static double getDouble(String key) {
      return prop.getDouble(key);
   }

   public static boolean getBoolean(String key) {
      return prop.getBoolean(key);
   }

   public static int getInt(String key, Integer defValue) {
      return prop.getInt(key, defValue);
   }

   public static double getDouble(String key, Double defValue) {
      return prop.getDouble(key, defValue);
   }

   public static boolean getBoolean(String key, Boolean defValue) {
      return prop.getBoolean(key, defValue);
   }
}
